/*
 *          Vanish Firefox Plugin MPL Version 1.1 License
 * 
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 * 
 * The Original Code is "Vanish Firefox Plugin"
 * 
 * The Initial Owner of the Original Code is the University of Washington.
 * The code is Copyright (C) 2009 by University of Washington. All
 * Rights Reserved.
 * 
 * Contributor(s): Amit Levy
 */

/*
   Class: Vanish
   This is the main kernel for Vanish
 */
function Vanish()
{	

    this.prefs = Components.classes["@mozilla.org/preferences-service;1"]
    .getService(Components.interfaces.nsIPrefService).getBranch("extensions.vanish.");

    
    Vanish.prototype.uuid = function()
    {
        var id;
        try
        {
            id = this.prefs.getCharPref("uuid");
        }
        catch (e)
        {
            var uuidGenerator = Components.classes["@mozilla.org/uuid-generator;1"]
            .getService(Components.interfaces.nsIUUIDGenerator);
            id = uuidGenerator.generateUUID().toString();
            this.prefs.setCharPref("uuid", id);
        }
        return id;
    }


    /*
        Function: encapsulate
        Return an encapsulated VDO.

        Parameters:
           slient - Set this to true to disable any alert for the user
           text - The text to sign
        */
    Vanish.prototype.encapsulate = function(text, callback, callFinal)
    {
        try {

            var vdoHeader = this.prefs.getCharPref("header");
            var vdoFooter = this.prefs.getCharPref("footer");
            var vdoHeaderText = this.prefs.getCharPref("header_text");

            var params = {};
            params.num_shares = this.prefs.getIntPref("num_shares");
            params.threshold = this.prefs.getIntPref("threshold");
            params.timeout_h = this.prefs.getIntPref("timeout_h");

            var xmlRpc = new XMLRpc(new XMLHttpRequest(), this.prefs
                .getCharPref("rpc_host"), 
                "RemoteVanish.encapsulate",
                [
                    new XMLRpcParam({
                        vid: this.uuid(),
                        ref: "" //content.document.domain
                    }),
                    new XMLRpcParam(VBase64.encode(text)),
                    new XMLRpcParam(params)
                ]);
            if (callback)
            {
                xmlRpc.callAsync
                (
                    function(response, time)
                    {
                        var date = new Date();
                        date.setHours(date.getHours() + params.timeout_h + 1);
                        response = vdoHeader + "\n" + vdoHeaderText +
                        "This message will self destruct by " +
                        date.toUTCString() + "\n" + "\n" + response +
                        "\n" + vdoFooter;
                        callback(response, time);
                    },
                    alert, callFinal);
            } 
            else
            {
                var response = xmlRpc.call();
                var date = new Date();
                date.setHours(date.getHours() + params.timeout_h + 1);
                response = vdoHeader + "\n" + vdoHeaderText +
                "This messgae will self destruct by " +
                date.toUTCString() + "\n" + "\n" + response +
                "\n" + vdoFooter;
                if (callFinal)
                {
                    callFinal();
                }
                return response;
            }
        }
        catch (e)
        {
            throw "Vanish encapsulation failed: " + e;
        }
    }

        

    /**
        Function: decapusate
        Return the string result from decapsulating a VDO.

        Parameters:
            slient - Set this to true to disable any alert for the user
            base64 - The base64 string represtenting the VDO to decapsulate
        */
    Vanish.prototype.decapsulate = function(base64, callback, callFinal)
    {
        try
        {
            //alert("ref: " + content.document.domain);
            var xmlRpc = new XMLRpc(
                        new XMLHttpRequest(),
                        this.prefs.getCharPref("rpc_host"),
                        "RemoteVanish.decapsulate",
                        [ new XMLRpcParam(
                            {
                            vid: this.uuid(),
                            ref : "" //ref: content.document.domain
                            }
                        ), new XMLRpcParam(new VBase64(base64)) ]
                    );
            if (callback)
            {
                xmlRpc.callAsync(callback, decapsulateError, callFinal);
            } 
            else
            {
                var response = xmlRpc.call();
                if (callFinal)
                {
                    callFinal();
                }
                return response.decode();
            }
        } 
        catch (e)
        {
            throw "Vanish decapsulation failed: " + e;
        }
    }

    Vanish.prototype.extractVDO = function(initial)
    {
        var vdoHeader = this.prefs.getCharPref("header");
        var vdoFooter = this.prefs.getCharPref("footer");
        var vdoHeaderText = this.prefs.getCharPref("header_text");
        var vdoRegExp = new RegExp(vdoHeader
            + "(?:.|\n)*?[^a-zA-Z0-9+=\/]{2}((?:[a-zA-Z0-9+=\/]+\n)+)[^a-zA-Z0-9+=\/]*"
            + vdoFooter);

        var before = initial.substring(0, initial.indexOf(vdoHeader));
        var footerPos = initial.search(
            /-----END[\s]+VANISH[\s]+MESSAGE-----/)
        var postFooterPos = initial.indexOf('\n', footerPos);
        var after = postFooterPos >= 0 ? initial.substring(postFooterPos, initial.length) : "";
        var result = initial.match(vdoRegExp);
        if (result) {
            return [ before, result[1].replace(/[^a-zA-Z0-9+=\/]/g,''), after ];
        } else {
        }

        return false;
    }
       
}
